use std::any::Any;
use std::fmt;
use std::time::Duration;
use async_trait::async_trait;
use thiserror::Error;
use std::sync::Arc;
use crate::supervision::Supervisor;
use crate::supervision_enum::SupervisorStrategyEnum;
use std::pin::Pin;
use std::future::Future;
use std::any::TypeId;
use crate::system::RequestMessage;
use crate::process::ProcessRegistry;
use tokio::sync::oneshot;
use tracing::{trace, debug, info, warn, error};
use crate::mailbox::{Mailbox, MessageInvoker};
// 导入 DispatcherTrait
use crate::dispatcher_enum;
use crate::dispatcher::DispatcherTrait;

// 从 pub(crate) mod 进行重新导出，使其可见
// pub use crate::dispatcher_enum::DispatcherTrait;

/// RequestContext for storing request information and response sender
#[derive(Debug)]
pub struct RequestContext {
    /// Sender channel to send response back to requester
    pub sender: crate::system::RequestSender,
    /// Trace ID for tracking request processing
    pub trace_id: String,
}

impl Clone for RequestContext {
    fn clone(&self) -> Self {
        // 创建一个新的通道，但原始功能将丢失
        let (tx, _) = oneshot::channel();
        Self {
            sender: tx,
            trace_id: self.trace_id.clone(),
        }
    }
}

/// Actor errors
#[derive(Debug, thiserror::Error)]
pub enum ActorError {
    /// Actor failed to process a message
    #[error("Actor failed: {0}")]
    ActorFailure(String),
    
    /// Actor panic
    #[error("Actor panicked")]
    ActorPanic,
    
    /// Message delivery failed
    #[error("Message delivery failed: {0}")]
    MessageDeliveryFailed(String),
    
    /// Dead letter - message sent to non-existent actor
    #[error("Dead letter: {0}")]
    DeadLetter(String),
    
    /// Timeout error
    #[error("Request timeout")]
    Timeout,
    
    /// Invalid response type
    #[error("Invalid response type, could not downcast to requested type")]
    InvalidResponse,
    
    /// Unknown error
    #[error("Unknown error: {0}")]
    Unknown(String),
}

/// Message trait for actor messages
pub trait Message: Send + 'static {}

impl<T> Message for T where T: Send + 'static {}

/// Responder trait for responding to messages - separated to make ActorContext object-safe
pub trait Responder: Send {
    /// Respond to a message with any type
    fn respond_any(&mut self, response: Box<dyn Any + Send + 'static>);
}

/// Actor context trait
#[async_trait]
pub trait ActorContext: Send {
    /// Get the actor's PID
    fn self_pid(&self) -> &PID;
    
    /// Get the parent PID if available
    fn parent(&self) -> Option<&PID>;
    
    /// Get the current message
    fn message(&self) -> &Box<dyn Any + Send>;
    
    /// Respond to the sender with a response
    fn respond<T: Any + Send + Sync + Clone + 'static>(&mut self, response: T);
    
    /// Forward the current message to another actor
    fn forward(&mut self, target: &PID);
    
    /// Spawn a new actor with the given props
    async fn spawn(&mut self, props: Props) -> PID;
    
    /// Spawn a named actor with the given props
    async fn spawn_named(&mut self, props: Props, name: &str) -> Result<PID, SpawnError>;
    
    /// Stop an actor
    async fn stop(&mut self, pid: &PID);
    
    /// Watch an actor for termination
    async fn watch(&mut self, pid: &PID);
    
    /// Unwatch an actor
    async fn unwatch(&mut self, pid: &PID);
}

/// Actor trait - defines the interface for all actors in the system
/// All actors must implement this trait
#[async_trait]
pub trait Actor: Send + Sync + 'static {
    /// The context type associated with this actor
    type Context: ActorContext;
    
    /// Receive a message
    async fn receive(&self, ctx: &mut Self::Context, msg: Box<dyn Any + Send>) -> Result<(), ActorError>;
    
    /// Called when the actor is started
    async fn started(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        Ok(())
    }
    
    /// Called when the actor is stopped
    async fn stopping(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        Ok(())
    }
    
    /// Called when the actor is restarted after failure
    async fn restarting(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        Ok(())
    }
}

/// Function-based actor
pub struct FnActor<F>
where
    F: Fn(&mut DefaultActorContext, Box<dyn Any + Send>) -> Pin<Box<dyn Future<Output = Result<(), ActorError>> + Send>> + Send + Sync + 'static,
{
    /// The function implementation
    f: F,
}

impl<F> FnActor<F>
where
    F: Fn(&mut DefaultActorContext, Box<dyn Any + Send>) -> Pin<Box<dyn Future<Output = Result<(), ActorError>> + Send>> + Send + Sync + 'static,
{
    /// Create a new function actor
    pub fn new(f: F) -> Self {
        Self { f }
    }
}

#[async_trait]
impl<F> Actor for FnActor<F>
where
    F: Fn(&mut DefaultActorContext, Box<dyn Any + Send>) -> Pin<Box<dyn Future<Output = Result<(), ActorError>> + Send>> + Send + Sync + 'static,
{
    type Context = DefaultActorContext;
    
    async fn receive(&self, ctx: &mut Self::Context, msg: Box<dyn Any + Send>) -> Result<(), ActorError> {
        (self.f)(ctx, msg).await
    }
}

/// PID (Process ID) - Represents an actor reference
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct PID {
    /// The address of the node where the actor is located
    pub address: String,
    /// The unique ID of the actor
    pub id: String,
}

impl PID {
    /// Create a new PID
    pub fn new(address: impl Into<String>, id: impl Into<String>) -> Self {
        Self {
            address: address.into(),
            id: id.into(),
        }
    }
    
    /// Send a message to the actor
    pub async fn send(&self, msg: impl Any + Send + Sync + 'static) -> Result<(), ActorError> {
        let registry = ProcessRegistry::new();
        
        let boxed_msg: Box<dyn Any + Send + Sync> = Box::new(msg);
        
        match registry.send_user_message(self, boxed_msg) {
            Ok(_) => Ok(()),
            Err(e) => Err(ActorError::MessageDeliveryFailed(e)),
        }
    }
    
    /// Send a message and wait for a response
    pub async fn request<R: Any + Send + Sync + 'static>(
        &self,
        msg: impl Any + Send + Sync + 'static,
        timeout: Duration,
    ) -> Result<R, ActorError> {
        // 创建一个 oneshot channel 用于接收响应
        let (sender, receiver) = tokio::sync::oneshot::channel();
        
        // 获取全局 ProcessRegistry
        let registry = ProcessRegistry::new();
        
        // 创建一个 RequestMessage
        let trace_id = uuid::Uuid::new_v4().to_string();
        trace!("[TRACE:{}] Creating RequestMessage with TypeId: {:?}", trace_id, std::any::TypeId::of::<Box<dyn Any + Send + Sync>>());
        let request_msg = crate::system::RequestMessage::new(
            Box::new(msg),
            sender,
            trace_id.clone(),
        );
        
        // 包装成 RequestEnvelope
        let envelope = crate::system::RequestEnvelope {
            trace_id: trace_id.clone(),
            type_tag: std::any::type_name::<R>().to_string(),
            request: request_msg,
        };
        
        // 发送请求前记录类型信息
        trace!("[TRACE:{}] Sending RequestEnvelope with TypeId: {:?}", trace_id, std::any::TypeId::of::<crate::system::RequestEnvelope>());
        trace!("[TRACE:{}] Sending RequestEnvelope via Box with TypeId: {:?}", trace_id, Box::new(envelope.clone()).type_id());
        trace!("[TRACE:{}] Address: {}, ID: {}", trace_id, self.address, self.id);
        
        // 发送请求
        match registry.send_user_message(self, Box::new(envelope)) {
            Ok(_) => {
                // 等待响应，带超时
                match tokio::time::timeout(timeout, receiver).await {
                    Ok(response_result) => {
                        match response_result {
                            Ok(response) => {
                                // 尝试将响应转换为期望的类型
                                trace!("[TRACE:{}] Received response, attempting to downcast to requested type", trace_id);
                                match response.downcast::<R>() {
                                    Ok(typed_response) => {
                                        trace!("[TRACE:{}] Successfully downcast response to requested type", trace_id);
                                        Ok(*typed_response)
                                    },
                                    Err(response) => {
                                        // 如果转换失败，记录更多信息以帮助调试
                                        error!("[TRACE:{}] Failed to downcast response to requested type", trace_id);
                                        error!("[TRACE:{}] Response type_id: {:?}, expected: {:?}", 
                                              trace_id, response.type_id(), std::any::TypeId::of::<R>());
                                        Err(ActorError::InvalidResponse)
                                    }
                                }
                            },
                            Err(e) => {
                                error!("[TRACE:{}] Response channel closed: {:?}", trace_id, e);
                                Err(ActorError::MessageDeliveryFailed("Response channel closed".to_string()))
                            },
                        }
                    },
                    Err(_) => {
                        error!("[TRACE:{}] Request timed out after {:?}", trace_id, timeout);
                        Err(ActorError::Timeout)
                    },
                }
            },
            Err(e) => {
                error!("[TRACE:{}] Failed to send request: {:?}", trace_id, e);
                Err(ActorError::MessageDeliveryFailed(e))
            },
        }
    }

    pub fn send_user_message(&self, boxed_msg: Box<dyn Any + Send + Sync>) -> Result<(), ActorError> {
        let registry = ProcessRegistry::new();
        match registry.send_user_message(self, boxed_msg) {
            Ok(_) => Ok(()),
            Err(e) => Err(ActorError::DeadLetter(e)),
        }
    }
}

impl fmt::Display for PID {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}@{}", self.id, self.address)
    }
}

/// Error that can occur when spawning an actor
#[derive(Debug, Error)]
pub enum SpawnError {
    #[error("name already taken: {0}")]
    NameTaken(String),
    #[error("actor system error: {0}")]
    SystemError(String),
}

/// Default actor context implementation
pub struct DefaultActorContext {
    /// The actor's PID
    self_pid: PID,
    /// The parent PID
    parent: Option<PID>,
    /// The current message
    message: Box<dyn Any + Send>,
}

impl DefaultActorContext {
    /// Create a new context
    pub fn new(self_pid: PID, parent: Option<PID>, message: Box<dyn Any + Send>) -> Self {
        Self {
            self_pid,
            parent,
            message,
        }
    }
}

#[async_trait]
impl ActorContext for DefaultActorContext {
    fn self_pid(&self) -> &PID {
        &self.self_pid
    }
    
    fn parent(&self) -> Option<&PID> {
        self.parent.as_ref()
    }
    
    fn message(&self) -> &Box<dyn Any + Send> {
        &self.message
    }
    
    fn respond<T: Any + Send + Sync + Clone + 'static>(&mut self, response: T) {
        debug!("[DefaultActorContext] Responding with type_id: {:?}", std::any::TypeId::of::<T>());
        debug!("[DefaultActorContext] Current message type_id: {:?}", self.message.type_id());
        
        // 创建一个标志，表示是否已经处理了响应
        let mut handled = false;
        
        // 尝试从引用角度处理已知请求类型
        if let Some(req_ctx) = self.message.downcast_ref::<crate::system::RequestContext>() {
            let trace_id = req_ctx.trace_id.clone();
            debug!("[DefaultActorContext] Found RequestContext, trace_id: {}", trace_id);
            
            // 我们不能通过引用发送响应，继续尝试其他方法
        }
        
        // 尝试使用消息克隆处理
        let msg_clone = format!("{:?}", self.message.type_id());
        if msg_clone.contains("RequestEnvelope") {
            debug!("[DefaultActorContext] Found RequestEnvelope type");
            
            // 替换原始消息，获取所有权
            let placeholder = Box::new(());
            let original = std::mem::replace(&mut self.message, placeholder);
            
            // 尝试转换为RequestEnvelope
            match original.downcast::<crate::system::RequestEnvelope>() {
                Ok(envelope) => {
                    // 成功转换为RequestEnvelope
                    let trace_id = envelope.trace_id.clone();
                    debug!("[DefaultActorContext] Processing RequestEnvelope (trace_id: {})", trace_id);
                    
                    // 尝试发送响应
                    let result = envelope.request.send_response(response.clone());
                    match result {
                        Ok(_) => {
                            debug!("[DefaultActorContext] Response sent successfully via RequestEnvelope");
                            // 创建一个新的空信封
                            let trace_id_clone = trace_id.clone();
                            self.message = Box::new(crate::system::RequestEnvelope {
                                trace_id: trace_id,
                                type_tag: "RESPONDED".to_string(),
                                request: crate::system::RequestMessage::new(
                                    Box::new(()),
                                    tokio::sync::oneshot::channel().0,
                                    trace_id_clone,
                                ),
                            });
                            handled = true;
                        },
                        Err(e) => {
                            warn!("[DefaultActorContext] Failed to send response: {}", e);
                            // 创建一个新的空信封
                            let trace_id_clone = trace_id.clone();
                            self.message = Box::new(crate::system::RequestEnvelope {
                                trace_id: trace_id,
                                type_tag: "FAILED".to_string(),
                                request: crate::system::RequestMessage::new(
                                    Box::new(()),
                                    tokio::sync::oneshot::channel().0,
                                    trace_id_clone,
                                ),
                            });
                        }
                    }
                },
                Err(original_restored) => {
                    // 转换失败，恢复原始消息
                    self.message = original_restored;
                    warn!("[DefaultActorContext] Failed to downcast to RequestEnvelope");
                }
            }
        }
        
        // 如果消息已经处理，直接返回
        if handled {
            return;
        }
        
        // 尝试使用系统辅助函数
        // Downcast 到适当的类型，而不是使用类型转换
        if let Some(boxed_any) = self.message.downcast_ref::<Box<dyn Any + Send + Sync>>() {
            debug!("[DefaultActorContext] Found Box<dyn Any + Send + Sync>");
            if crate::system::try_respond_to_request(boxed_any, response.clone()) {
                debug!("[DefaultActorContext] Response sent via system helper");
                return;
            }
        }
        
        // 所有尝试失败，记录警告
        warn!("[DefaultActorContext] Could not respond to message: no suitable request context found");
    }
    
    fn forward(&mut self, _target: &PID) {
        // Will be implemented when we have the full message handling system
    }
    
    async fn spawn(&mut self, _props: Props) -> PID {
        // Will be implemented when we have the actor system
        PID::new("local", uuid::Uuid::new_v4().to_string())
    }
    
    async fn spawn_named(&mut self, _props: Props, name: &str) -> Result<PID, SpawnError> {
        // Will be implemented when we have the actor system
        Ok(PID::new("local", name.to_string()))
    }
    
    async fn stop(&mut self, _pid: &PID) {
        // Will be implemented when we have the actor system
    }
    
    async fn watch(&mut self, _pid: &PID) {
        // Will be implemented when we have the actor system
    }
    
    async fn unwatch(&mut self, _pid: &PID) {
        // Will be implemented when we have the actor system
    }
}

/// Props is a configuration object used to create an actor.
pub struct Props {
    /// The function that creates the actor
    pub producer: Arc<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>,
    /// The dispatcher to use for the actor
    pub dispatcher: Option<Arc<dyn crate::dispatcher::DispatcherTrait>>,
    /// The function that creates the mailbox
    pub mailbox_producer: Arc<dyn Fn(Arc<dyn MessageInvoker>, Arc<dyn crate::dispatcher::DispatcherTrait>) -> Box<dyn Mailbox> + Send + Sync>,
}

// 手动实现 Clone，使用 Arc 的 Clone 功能
impl Clone for Props {
    fn clone(&self) -> Self {
        Self {
            producer: self.producer.clone(),
            dispatcher: self.dispatcher.clone(),
            mailbox_producer: self.mailbox_producer.clone(),
        }
    }
}

impl Props {
    /// Create a new Props with the given producer function
    pub fn new<F>(producer: F) -> Self
    where
        F: Fn() -> Box<dyn Any + Send + Sync> + Send + Sync + 'static,
    {
        Self {
            producer: Arc::new(producer),
            dispatcher: None,
            mailbox_producer: Arc::new(|invoker, dispatcher| {
                let mailbox = crate::mailbox::DefaultMailbox::new(invoker, dispatcher);
                Box::new(mailbox)
            }),
        }
    }
    
    /// Set the dispatcher for the actor
    pub fn with_dispatcher(mut self, dispatcher: Arc<dyn crate::dispatcher::DispatcherTrait>) -> Self {
        self.dispatcher = Some(dispatcher);
        self
    }
    
    /// Set the mailbox producer for the actor
    pub fn with_mailbox_producer<F>(mut self, producer: F) -> Self
    where
        F: Fn(Arc<dyn MessageInvoker>, Arc<dyn crate::dispatcher::DispatcherTrait>) -> Box<dyn Mailbox> + Send + Sync + 'static,
    {
        self.mailbox_producer = Arc::new(producer);
        self
    }
}

/// Dispatcher trait - responsible for scheduling message processing
#[async_trait]
pub trait Dispatcher: Send + Sync {
    /// Schedule a function to be executed
    async fn schedule<F>(&self, f: F)
    where
        F: FnOnce() -> Box<dyn std::future::Future<Output = ()> + Send + Unpin> + Send + 'static;
    
    /// Get the throughput (number of messages to process in a batch)
    fn throughput(&self) -> usize;
}

/// System message types
#[derive(Debug)]
pub enum SystemMessage {
    /// Stop the actor
    Stop,
    /// Restart the actor
    Restart,
    /// Resume the actor after suspension
    Resume,
    /// Suspend the actor
    Suspend,
    /// Terminated notification
    Terminated(PID),
    /// Watch an actor
    Watch(oneshot::Sender<()>),
    /// Unwatch an actor
    Unwatch(oneshot::Sender<()>),
}

/// SupervisorStrategy - Defines how to handle actor failures
pub trait SupervisorStrategy: Send + Sync {
    /// Handle a failure
    async fn handle_failure(
        &self,
        ctx: &mut DefaultActorContext,
        pid: &PID,
        reason: &ActorError,
        message: Option<Box<dyn Any + Send>>,
    ) -> SupervisorDirective;
}

/// Supervisor directives
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SupervisorDirective {
    /// Resume the actor
    Resume,
    /// Restart the actor
    Restart,
    /// Stop the actor
    Stop,
    /// Escalate the failure to the parent
    Escalate,
}

/// Adapter for converting between mailbox::Mailbox and actor::Mailbox
pub struct MailboxAdapter {
    inner: Box<dyn crate::mailbox::Mailbox>,
}

impl MailboxAdapter {
    /// Create a new mailbox adapter
    pub fn new(inner: Box<dyn crate::mailbox::Mailbox>) -> Self {
        trace!("[MailboxAdapter] Creating new mailbox adapter");
        Self { inner }
    }
}

impl crate::mailbox::Mailbox for MailboxAdapter {
    fn start(&self) {
        trace!("[MailboxAdapter] Starting mailbox");
        self.inner.start();
    }
    
    fn post_user_message(&self, msg: Box<dyn Any + Send + Sync>) -> Result<(), ActorError> {
        trace!("[MailboxAdapter] Posting user message to inner mailbox, type_id: {:?}", msg.type_id());
        self.inner.post_user_message(msg)
    }
    
    fn post_system_message(&self, msg: SystemMessage) -> Result<(), ActorError> {
        trace!("[MailboxAdapter] Posting system message to inner mailbox: {:?}", msg);
        self.inner.post_system_message(msg)
    }
    
    fn process_messages(&self) {
        trace!("[MailboxAdapter] Processing messages");
        self.inner.process_messages();
    }
}

impl std::fmt::Debug for MailboxAdapter {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("MailboxAdapter").finish()
    }
}

// 确保MailboxAdapter是Send + Sync
unsafe impl Send for MailboxAdapter {}
unsafe impl Sync for MailboxAdapter {} 